class UniWebSocket {
  constructor(url) {
    this.url = url || '';
    this.websocket = null;
    this.socketOpen = false;
    this.heartbeatOpen = false;
    this.heartbeatTimer = null;
    this.heartbeatInterval = 5000;
    this.heartbeatMsgBody = null;
    this.isReconnect = true;
    this.reconnectCount = 3;
    this.reconnectCurrent = 0;
    this.reconnectTimer = null;
    this.reconnectInterval = 5000;
    this.sendInterval = 1000;
    this.registerCallBack = null;
  }

  configure(options) {
    if (options.url) {
      this.url = options.url;
    }
    if (options.heartbeat) {
      this.setHeartBeatOption(options.heartbeat);
    }
    if (options.reconnect) {
      this.setReconnectOption(options.reconnect);
    }
    if (options.sendInterval) {
      this.setSendOption(options.sendInterval);
    }
    if (options.onMessage) {
      this.setRegister(options.onMessage);
    }
    if (options.onOpen) {
      this.onOpen = options.onOpen;
    }
    if (options.onClose) {
      this.onClose = options.onClose;
    }
    if (options.onError) {
      this.onError = options.onError;
    }
  }

  setHeartBeatOption({ open, interval, msgBody }) {
    this.heartbeatOpen = open;
    this.heartbeatInterval = interval;
    this.heartbeatMsgBody = msgBody;
  }

  setReconnectOption({ open, count, interval }) {
    this.isReconnect = open;
    this.reconnectCount = count;
    this.reconnectInterval = interval;
  }

  setSendOption(interval) {
    this.sendInterval = interval;
  }

  setRegister(callBack) {
    this.registerCallBack = callBack;
  }

  unRegister() {
    this.registerCallBack = null;
  }

  getWebSocket() {
    return {
      socketOpen: this.socketOpen,
      websocket: this.websocket
    };
  }

  init(url) {
    if (url) {
      this.url = url;
    }

    if (this.socketOpen) {
      return;
    }

    this.websocket = uni.connectSocket({
      url: this.url,
      success: () => {
        console.log('WebSocket连接成功');
        this.socketOpen = true;
        this.reconnectCurrent = 0;

        if (this.reconnectTimer) {
          clearTimeout(this.reconnectTimer);
          this.reconnectTimer = null;
        }

        if (this.heartbeatOpen) {
          this._startHeartBeat();
        }

        if (this.onOpen) {
          this.onOpen();
        }
      },
      fail: (err) => {
        console.error('WebSocket连接失败', err);
        this.socketOpen = false;
        if (this.onError) {
          this.onError(err);
        }
      }
    });

    this.websocket.onMessage((res) => {
      if (this.registerCallBack) {
        this.registerCallBack(res.data);
      }
    });

    this.websocket.onClose((res) => {
      console.log('WebSocket已关闭', res);
      this.socketOpen = false;

      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }

      if (this.isReconnect) {
        this.reconnectTimer = setTimeout(() => {
          if (this.reconnectCurrent >= this.reconnectCount) {
            console.log('重连次数已达上限');
            if (this.reconnectTimer) {
              clearTimeout(this.reconnectTimer);
              this.reconnectTimer = null;
            }
            return;
          }
          this.reconnectCurrent++;
          this._reconnect();
        }, this.reconnectInterval);
      }

      if (this.onClose) {
        this.onClose(res.code);
      }
    });

    this.websocket.onError((err) => {
      console.error('WebSocket发生错误', err);
      if (this.onError) {
        this.onError(err);
      }
    });
  }

  _startHeartBeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }

    this.heartbeatTimer = setInterval(() => {
      this.send(this.heartbeatMsgBody);
    }, this.heartbeatInterval);
  }

  _reconnect() {
    console.log(`正在发起重新连接，第${this.reconnectCurrent}次`);
    if (this.websocket && this.socketOpen) {
      this.websocket.close();
    }
    this.init();
  }

  send(data, callback) {
    if (!(this.socketOpen && this.websocket)) {
      console.log('WebSocket未开启或已断开');
      return;
    }

    if (this.websocket.readyState === this.websocket.OPEN) {
			console.log('发送消息');
      this.websocket.send({
        data: JSON.stringify(data),
        success: () => {
          if (callback) {
            callback();
          }
        },
        fail: (err) => {
          console.error('发送消息失败', err);
        }
      });
    } else if (this.websocket.readyState === this.websocket.CONNECTING) {
      setTimeout(() => {
        this.send(data, callback);
      }, this.sendInterval);
    } else {
      if (this.heartbeatOpen) {
        this.init();
        setTimeout(() => {
          this.send(data, callback);
        }, this.sendInterval);
      } else {
        console.log('WebSocket连接已关闭');
      }
    }
  }

  close() {
    if (this.websocket && this.socketOpen) {
      console.log('主动关闭连接');
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }
      this.isReconnect = false;
      this.websocket.close();
      this.socketOpen = false;
    }
  }
}

export default UniWebSocket;
